"""
PCMCIEngine 模块 - 基于PCMCI算法的因果发现

PCMCI 是一种专为时序数据设计的因果发现算法，结合了PC算法和条件独立性测试，
能够处理时间滞后效应和非线性因果关系，适用于K8s系统监控数据的因果分析
"""

import numpy as np
import pandas as pd
import logging
from typing import Dict, List, Tuple
from tigramite.pcmci import PCMCI
from tigramite.independence_tests.parcorr import ParCorr

from .baseEngine import baseCasualEngine

logger = logging.getLogger(__name__)


class PCMCIEngine(baseCasualEngine):
    """基于PCMCI算法的因果分析引擎"""

    def __init__(self, config):
        """
        初始化PCMCIEngine
        Args:
            config: 配置对象，包含以下特定配置：
                - CASUAL_ALPHA: 显著性水平
                - MAX_LAG: 最大时滞
                - PC_ALPHA: PC算法的显著性水平
                - TEST_TYPE: 条件独立性检验类型
        """
        super().__init__(config)
        self.alpha = getattr(config, "PC_ALPHA", 0.05)  # 显著性水平
        self.tau_min = 0  # 最小时滞
        self.tau_max = getattr(config, "MAX_LAG", 6)  # 最大时滞
        self.cond_ind_test = self._get_cond_ind_test(
            getattr(config, "PCMCI_TEST_TYPE", "linear")
        )

    def _get_cond_ind_test(self, test_type: str):
        """
        获取条件独立性检验器
        Args:
            test_type: 检验类型，支持 linear/gass/cmiknn/cmisymb
        Returns:
            条件独立性检验器实例
        """
        # 从配置中获取并行作业数，默认为1 (无并行)
        n_jobs_ci_test = getattr(self.config, "PCMCI_COND_IND_TEST_N_JOBS", 4)
        if n_jobs_ci_test != 1:
            logger.info(f"为CMIknn/CMIsymb配置的并行作业数 (n_jobs): {n_jobs_ci_test}")
            
        test_params = {
            "linear": {"class": ParCorr, "params": {"significance": "analytic"}},
       }

        if test_type in test_params:
            test_config = test_params[test_type]
            return test_config["class"](**test_config["params"], verbosity=0)

        logger.warning(f"未知的测试类型: {test_type}，使用默认的ParCorr")
        return test_params["linear"]["class"](
            **test_params["linear"]["params"], verbosity=0
        )

    def _run_algorithm(self, data: pd.DataFrame) -> Dict:
        """
        执行PCMCI算法
        Args:
            data: 输入数据
        Returns:
            包含检验结果的字典
        """
        try:
            # 创建Tigramite数据框架
            dataframe = pp.DataFrame(
                data.values, var_names=data.columns, datatime=data.index.values
            )

            # 创建PCMCI对象并执行分析
            pcmci = PCMCI(
                dataframe=dataframe, cond_ind_test=self.cond_ind_test, verbosity=0
            )

            # 执行PCMCI分析
            results = pcmci.run_pcmci(
                tau_min=self.tau_min,
                tau_max=self.tau_max,
                pc_alpha=self.alpha,
                fdr_method="none",
            )

            return {
                "val_matrix": results["val_matrix"],
                "p_matrix": results["p_matrix"],
                "alpha": self.alpha,
            }
        except Exception as e:
            logger.error(f"PCMCI分析失败: {str(e)}")
            n_vars = data.shape[1]
            return {
                "val_matrix": np.zeros((n_vars, n_vars, self.tau_max)),
                "p_matrix": np.ones((n_vars, n_vars, self.tau_max)),
                "alpha": self.alpha,
            }

    def _get_method_name(self) -> str:
        """获取算法方法名称"""
        return "PCMCI"
